package com.googlecode.curvedmetromaps.core.model.importer;

import com.googlecode.curvedmetromaps.core.model.MetroMap;
import playn.core.AssetWatcher;
import playn.core.PlayN;
import playn.core.util.Callback;

public class MapLoader {

	/**
	 * Creates a MetroMap instance from a file path.
	 * @param path JSON or OSM XML file path.
	 * @param callback Callback that gets called when the map is loaded.
	 * @see <a href="http://wiki.openstreetmap.org/wiki/OSM_XML">OSM XML</a>
	 */
	public static void load(final String path, final Callback<MetroMap> callback) {
		// Object that is given to the callback function
		final MetroMap map = new MetroMap();

		// load the map
		PlayN.assets().getText(path, new Callback.Chain<String>(callback) {
			@Override
			public void onSuccess(String resource) {
				// Create an asset watcher that will call our callback when all
				// assets are loaded.
				AssetWatcher watcher = createAssetWatcher(map, callback);

				// Parse map
				MapParser mapParser = MapParserFactory.createParser(resource, path);
				mapParser.parse(resource, map);

				// start watcher (will call callback when everything is loaded)
				watcher.start();
			}
		});
	}

	/**
	 * Creates an asset watcher that chains the asset loading to a callback.
	 * @return The asset watcher. Call {@link playn.core.AssetWatcher.start()}
	 *         when resource is processed.
	 */
	private static AssetWatcher createAssetWatcher(final MetroMap metroMap, final Callback<MetroMap> callback) {
		return new AssetWatcher(new AssetWatcher.Listener() {
			@Override
			public void done() {
				callback.onSuccess(metroMap);
			}

			@Override
			public void error(Throwable e) {
				callback.onFailure(e);
			}
		});
	}
}
